加密与解密 第2篇 调试篇

第二章 动态分析技术

2.1 ollyDbg

2.1.1 ollyDbg界面

  • 窗口

CPU等各窗口

  • CPU面板窗口

  • 反汇编

    • address列

    • hex dump列

    快捷键:F2设置断点

    • Disassemly列

    • comment

    快捷键:;

    • 多行选择

    • shift+键盘上下

    • ctrl+鼠标
  • 信息

    • 与指令相关的寄存器值
    • api调用提示
    • 跳转提示
  • 数据

    • 十六进制显示文件在内存中的数据
  • 寄存器

  • 堆栈

2.1.2 OllyDbg的设置

界面设置
  • udd文件和插件路径设置

options -> appearance-> Directores

设置成绝对路径

  • udd文件

保存当前调试的一些状态

  • 断点
  • 注释等

  • 插件

调试设置

Options -> Debugging options

忽略各种异常

加载符号文件
  • 让ollydbg以函数名显示DLL中的函数

Debug->select import libraries

关联到右键

Options/add to explorer->Add ollydbg to menu...

2.1.3 加载程序

createProces创建进程
附加到一个运行的进程上

File/Attach

  • 隐藏进程的附加

shell ollydbg.exe -p pid值

  • 附加不成功

  • a.exe 调用b.exe

  • b.exe附加不成功
  • 设置olldbg为Just-in-time debugging
  • 修改b.exe的入口点指令为CC(int 3)
  • 运行a.exe
  • b.exe运行到int 3异常
  • 还原原指令,继续调试

2.1.4 基本操作

  1. 准备工作

  2. 加载目标文件调试

Options/Debugging Options -> Event

断点设置:

  • system breakpoints: int3
  • Entry point of main module:主模块的入口点
  • winMain: 即使设置了这个选项,一般也会断在文件入口点

  • 断点跟踪

功能键 功能
F7 单步步进
F8 单步步过
Ctrl+F9 直到出现Ret指令时中断
alt+F9 若进入系统领空,瞬间返回应用程序领空
F9 运行程序
ctlr+F2 重新调试应用程序
F12 暂停程序,程序进入死循环时可以使用
F2 设置/取消断点
alt+B 打开断点窗口(不显示硬件断点)
ctrl+N 打开应用程序输入表
F3 打开文件
F5 显示各个窗口,双击返回当前窗口
ALT+M 显示内存
F4 执行到光标所在行
shift+F2 条件断点
shift+F4 条件记录断点
Alt+F7 转到上一个找到的参考
Alt+F8 转到下一个找到参考
Ctrl+R 搜索所选命令的参考。该命令扫描激活模块的全部可执行代码,以找到涉及到首个选中的命令的全部相关参考(包括:常量、跳转及调用),您可以在参考中使用快捷键 Alt+F7 和 Alt+F8来浏览这些参考。为便于您使用,被参考的命令也包含在该列表中。
  • 需要多次按F7或者F8键时,可以按ctrl+F7或者ctlr+F8,直到ESC、F12或者遇到其他断点中止

  • 设置断点

  • 在特定表达式上设置断点

    • Ctrl+G : 打开跟随表达式窗口(e.g GetDlgItemTextA
    • F2 设置断点
    • win9x系统中,ollydbg无法对api函数设断点
    • 在输入表中设置断点
    • Ctrl+N 打开输入表
    • 找到要找的函数
    • enter或者右键"Find references to import"命令打开调用此函数的参考代码窗口,找到相应的代码
    • enter切换到相应的代码
    • F2设置断点
  • 调试分析

  • 程序中断后,alt+f9回到调用函数的地方

  • alt+b,禁用掉getDlgItemTextA断点
  • 为了方便反复调试,在调用出设置断点

代码阅读

  1. API定义

  2. 调用约定

    • __stdcall
      • 参数从右向左顺序入栈
      • 由被调用者清理堆栈中的参数
      • 返回值保存在eax中
    • C调用
      • 参数从右向左顺序入栈
      • 由调用者清理堆栈参数
  3. 查看指定地址处内存值的变化

    e.g push eax

    1. 在当前代码行暂停
    2. eax寄存器窗口上右键,执行"Follow Dump",查看数据窗口
    3. 单步执行call GetDlgItemTextA完成
    4. 已经看到内存中值的变化
  4. 保存修改后的文件

e.g : je short 0040122E

  • 修改ZF标志位,单击取反
  • 修改改行代码为9090
  • 鼠标右键,copy to executable/Selection
  • save File

  • 算法分析

2.1.5 断点

  1. int 3断点

  2. 原理:其机器码是CCh,也常称为CC指令,当被调试进程执行INT3指令导致一个异常时,调试器会捕捉这个异常从而停在断点处,然后将该断点处的指令恢复成原来指令

Ø 优点:可以设置无数个断点

Ø 缺点:改变了原程序指令,容易被软件检测到

Ø 设置方法:F2设置(就是普通的断点) F2取消

  1. 硬件断点

  2. 原理:硬件断点和DRx调试寄存器有关,DRx有8个寄存器

    DR0~3:调试地址寄存器,保存需要监视的地址,如设置硬件断点

    DR4~5:保留

    DR6:调试寄存器组状态寄存器

    DR7:调试寄存器组控制寄存器

硬件断点是使用DR0 DR1 DR2 DR3来设置断点

Ø 优点:断点速度快,不容易被发现

Ø 缺点:只能设置4个断点DR0 DR1 DR2 DR3

Ø 设置方法:F8到需要设置的位置,右键“Breakpoint/Hardware,on execution”

  1. 内存断点

Ø 原理:OD可以设置内存访问断点或内存写入断点,原理是对所设的地址设为不可访问/不可写属性,同样当访问/写入的时候会报异常,并且停留在异常处

Ø 优点:内存断点不修改原代码。它不像INT3断点,因为修改程序代码而导致中断,因此在遇到代码校验,并且硬件断点失灵情况下,可以用内存断点来代替

Ø 缺点:只能设置1次

Ø 设置方法:

​ 右键->Breakpoint->Memory ,on access(断点/内存写入)

​ ->Memory ,on write(断点/内存访问)

  1. 内存访问一次性断点

Ø 原理:原理和”Set memory breakpoint on access”功能一样

Ø 优点:对整个内存块设置断点,快捷键也是F2

Ø 特点:一次性断点,当所在段读取或执行时就中断,中断发生以后,断点将被删除

Ø 设置方法:ALT+M 右键->”Set break-on-access”

  1. 消息断点

  2. 原理:Windows本身是由消息驱动的,如果调试时没有合适的断点,额可以尝试消息断点

  3. 如何中断返回

    1. 在中断后,由于处在系统代码底层,所以alt+F9或者ctrl+F9,无法回到程序的代码领空
    2. 所以,需要在.txt段中设置内存访问断点set break-on-access
    3. F9运行
    4. 由于中断的地方可能不是想要的消息,所以,可能需要重复1-3步数次,最后发现check按钮事件代码
    5. alt+b进入断点窗口,删除消息断点
  4. 条件断点

  5. 条件记录断点

2.1.6 插件

  1. 常用插件

  2. command bar

    alt +F1 快速显示/隐藏command bar

    cltr+D 快速定位到输入框

  3. 插件开发

2.1.7 run trace

2.1.8 hit trace

2.1.9 符号调试技术

  1. 符号格式

  2. 将16进制数转换为源文件代码行、函数名以及变量名称

  3. 创建调试文件

以vc6.0为例,建立带有pdb调试信息的调试版本:

  • bulild -> set active configuration -> win32 debug
  • project -> settings -> c/c++ -> category -> general -> debug info -> program database 产生pdb文件
  • link -> category -> debug -> debug info & microsoft format & separate types & generate mapfiles 产生map文件

  • 用符号文件调试

  • debugging options -> cpu -> synchronize soure with cpu 选中

  • cpu窗口-> 单击comment栏 -> 切换到source
  • debugging options -> debug -> hide none-existing source files 取消选中
  • view/source files 选中正确的源文件
  • view/source 打开源代码窗口,就可以看到源码
  • 在源码窗口下断点,F9运行,就可以正常在源码和反汇编窗口同步调试应用程序了

2.1.10 OllyDbg常见问题

  1. 乱码的问题

  2. 如何快速回到当前领空

双击寄存器窗口的EIP

  1. Ollydbg如何修改EIP

Ctlr+* 发现笔记本键盘无效:cry:

  1. 什么是UDD

所有程序或模组相关的信息

  1. 删除了断点,重新加载时,会重新出现

ollydbg.ini -> 修改为 bacup UDD files=1

  1. push E000未知字符

0E000 -> 0E000

  1. 假死

ollydbg.ini -> restore windows=0

  1. 微调窗口显示

ctrl+↑ 或者 ctrl+↓ 上下翻动一个字节

  1. “复制到可执行文件”-> 报错:“Unable to locate data in executable file”

修改的地方不在raw size范围内,修改pe文件,是rawSize=VirtualSize

  1. 能否把call调用修改为函数名称形式

    shift+;-> 输入函数名称

2.2 softice调试器